using UnityEngine;
using System;
using System.IO;
using System.Text;
using System.Collections;
using System.Collections.Generic;

public class InitCamera : MonoBehaviour
{

	// Exposed variables
	public Transform target;
	public float distance = 5.0f;
	public float height = 1.0f;
	public float heightDamping = 0.5f;
	public float rotationDamping = 0.1f;

	public Galaxy galaxy;
	public StarSystem starsystem;
	public bool follow = true;

	public List<StarSystem> lSolars = new List<StarSystem>();
	private bool freeze = false;

	public float currentZ;
	public float nearZoom = 10.0f;				// for the control of camera zoom range
	public float farZoom = -15.0f;

	float angleMax = 0.0f;
	float allowX = 120.0f;								// controls angle allowed for rotating camera

	float posY;

	private Kingdom curKingdom;						// current Kingdom

	// Use this for initialization
	void Awake()
	{
		if (!Directory.Exists("Saves"))
			Directory.CreateDirectory("Saves");

		new Core();
		Core.Init();

		//foreach (StarSystem ss in Core.Stars.Values)
		//  Debug.Log("Star: " + ss.StarName + ", ID: " + ss.StarID.ToString());

		//foreach (Planet pl in Core.Planets.Values)
		//  Debug.Log("Planet: " + pl.PlanetName + " |" + pl.PlanetID);

	}

	void Start()
	{
		galaxy = Core.mainGalaxy;
		starsystem = Core.galaxyKingdoms[0].Home;
		curKingdom = Core.galaxyKingdoms[0];
	}

	void LateUpdate()
	{
		if (null == target || !follow || Core.shutMain)
			return;

		// Calculate the current rotation angles
		float wantedRotationAngle = target.eulerAngles.y;
		float wantedHeight = target.position.y + height;

		float currentRotationAngle = transform.eulerAngles.y;
		float currentHeight = transform.position.y;

		Vector3 oldpos = transform.position;

		// Damp the rotation around the y-axis
		currentRotationAngle = Mathf.LerpAngle(currentRotationAngle, wantedRotationAngle, 4.0f * rotationDamping * Time.deltaTime);

		// Damp the height
		currentHeight = Mathf.Lerp(currentHeight, wantedHeight, 4.0f * heightDamping * Time.deltaTime);

		// Convert the angle into a rotation
		Quaternion currentRotation = Quaternion.Euler(0, currentRotationAngle, 0);

		// Set the position of the camera on the x-z plane to:
		// distance meters behind the target
		transform.position = target.position;

		transform.position -= (Vector3)(currentRotation * Vector3.forward * distance) * 1.25f;

		// Set the height of the camera
		transform.position = new Vector3((transform.position.x), currentHeight, transform.position.z);

		// Always look at the target
		transform.LookAt(target);

		// star system in focus
		Core.solarOnShow = starsystem;

		if (transform.position == oldpos)				// damping finished
		{
			currentZ = 0;					// default camera z-position
			follow = false;

			angleMax = 0.0f;
			posY = transform.position.y;
		}
	}

	// Update is called once per frame
	void Update()
	{
		// to get user input
		// transform.Translate(Input.GetAxis("Horizontal"), 0, Input.GetAxis("Vertical"));
		if (galaxy == null || Core.shutMain)
			return;

		if (target && !follow)
		{
			float z = 0;

			// detect visit key
			int detect = 0;
			if (Input.GetKey("left"))
				detect = -1;
			else if (Input.GetKey("right"))
				detect = 1;

			// if (Input.GetKey("left") || Input.GetKey("right"))
			if (detect != 0)
			{
				PreviousNextStar(detect);

			}

			// to zoom in and out
			bool guiActive = GameObject.Find("guiCamera").GetComponent<GuiCamera>().techButton;

			if (!guiActive)
			{
				if (Input.GetAxis("Mouse ScrollWheel") != 0)
					z = 8.0f * Input.GetAxis("Mouse ScrollWheel");

				if (Input.GetAxis("Vertical") != 0)
					z = 0.05f * Input.GetAxis("Vertical");

				currentZ += z;

				if (currentZ < nearZoom && currentZ > farZoom)
					transform.Translate(0, 0, z);

				if (currentZ > nearZoom)
					currentZ = nearZoom;
				else if (currentZ < farZoom)
					currentZ = farZoom;
			}

			// to rotate camera around sun
			if (!Input.GetMouseButtonUp(1) && Input.GetMouseButton(1))
			{
				angleMax += Input.GetAxis("Mouse X");

				// set angleMax to 5~10 if control is needed
				if (angleMax > allowX)
					angleMax = allowX;
				else if (angleMax < -allowX)
					angleMax = -allowX;

				if (angleMax > -allowX && angleMax < allowX)
					transform.RotateAround(target.transform.position, Vector3.up, 15.0f * Input.GetAxis("Mouse X"));

				posY += Input.GetAxis("Mouse Y") * 0.5f;
				Vector3 pos = new Vector3(transform.position.x, posY, transform.position.z);

				transform.position = pos;	
			}

			if (!Input.GetMouseButtonUp(0) && Input.GetMouseButton(0))
			{

			}

		}

	}

	void FixedUpdate()
	{
		//if (Core.shutMain)						// don't do anything is main camera is not used
		//  return;

		if (lSolars.Count > 0)
		{
			freeze = true;

			Core.oGuiCam.GetComponent<GuiCamera>().strCommand = "Please select a planet to dock your ColonyBase!";
			Core.oGuiCam.GetComponent<GuiCamera>().isTop = true;
		}

		if (freeze)
		{
			if (lSolars.Count == 0)
			{
				Core.oGuiCam.GetComponent<GuiCamera>().isTop = false;
				freeze = false;
				return;
			}

			bool keep = false;

			// to update the lSolars list
			for (int i = 0; i < lSolars.Count; i++)
			{
				foreach (Planet pl in lSolars[i].Planets)
					if (pl.Status == Planet.PlanetStatus.None)
						keep = true;

				if (!keep)			// failed to find available planet to dock colony base
				{
					Debug.Log("Colony Status: " + lSolars[i].ColonyBase[0] + "|" + lSolars[i].ColonyBase[1] + "|" + lSolars[i].ColonyBase[2] + "|" + lSolars[i].ColonyBase[3]);

					// to remove excess colony base
					if (lSolars[i].SolarColony.ContainsKey(Core.galaxyKingdoms[0]) && (int)lSolars[i].SolarColony[Core.galaxyKingdoms[0]] > 0)
					{
						lSolars[i].SolarColony[Core.galaxyKingdoms[0]] = 0;
						lSolars[i].ColonyBase = new int[] { 0, 0, 0, 0 };
						lSolars[i].FindMaxColonyBase();
					}

				}

				if (keep)			// there are available new colony base, to see if all the colony base to planet conversions are done
				{
					keep = false;

					// to see if new colony base is available
					if (lSolars[i].SolarColony.ContainsKey(Core.galaxyKingdoms[0]) && (int)lSolars[i].SolarColony[Core.galaxyKingdoms[0]] > 0)
						keep = true;
				}

				if (!keep)
					lSolars.RemoveAt(i--);
			}

			// control player display
			if (!Core.shutMain && (Core.solarOnShow == null || (lSolars.Count > 0 && lSolars[0] != Core.solarOnShow)))
			{
				VisualMisc.RunStopStarSystem(lSolars[0], true);
				Core.oMainCam.GetComponent<InitCamera>().starsystem = lSolars[0];
				Core.oMainCam.GetComponent<InitCamera>().target = lSolars[0].Sunlight.transform;
				Core.oMainCam.GetComponent<InitCamera>().follow = true;
			}

		}
	}

	public void PreviousNextStar(int detect)
	{
		target = null;

		StarSystem star = VisualMisc.ScrollStarSystems(Core.mainGalaxy.Solars, starsystem, detect);
		// VisualMisc.RunStopStarSystem(starsystem, false);			// turn off current solar
		RunVisualStar(star);
	}

	public void ScrollKingdomSolars(int offset)							// to scroll current kingdom reachable solars
	{
		target = null;
		List<StarSystem> lstars = new List<StarSystem>();

		foreach (Kingdom.SolarPlanet sp in curKingdom.Planets)
			lstars.Add(sp.pSolar);

		StarSystem star = VisualMisc.ScrollStarSystems(lstars, starsystem, offset);
		RunVisualStar(star);
	}

	public void ScrollSolars(int offset, int flag)			//0 - in list, 1 - conquered only, 2 - non-conquered only
	{
		target = null;
		List<StarSystem> lstars = new List<StarSystem>();

		foreach (Kingdom.SolarPlanet sp in Core.galaxyKingdoms[0].Planets)
		{
			if (flag == 1 && !Kingdom.SolarOwned(Core.galaxyKingdoms[0], sp.pSolar))
				continue;

			if (flag == 2 && Kingdom.SolarOwned(Core.galaxyKingdoms[0], sp.pSolar))
				continue;

			lstars.Add(sp.pSolar);
		}

		StarSystem star = VisualMisc.ScrollStarSystems(lstars, starsystem, offset);
		RunVisualStar(star);
	}

	public void ReturnHome()
	{
		target = null;

		StarSystem star = Core.galaxyKingdoms[0].Home;
		RunVisualStar(star);

		curKingdom = Core.galaxyKingdoms[0];
	}

	public void ScrollHomes()
	{
		target = null;
		List<StarSystem> lstars = new List<StarSystem>();

		foreach (Kingdom kdm in Core.galaxyKingdoms)
			lstars.Add(kdm.Home);

		StarSystem star = VisualMisc.ScrollStarSystems(lstars, starsystem, 1);
		RunVisualStar(star);

		// to decide current Kingdom
		if (star.OwnedBy.Count > 0)
			curKingdom = star.OwnedBy[0];			// in case of shared solar, first kingdom will be taken
	}

	public void RunVisualStar(StarSystem star)
	{
		VisualMisc.RunStopStarSystem(star, true);

		starsystem = star;
		target = star.Sunlight.transform;
		follow = true;
	}
}
